package com.tianzmp.ttq.admin.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tianzmp.ttq.admin.controller.reqDto.UserInfoSaveDTO;
import com.tianzmp.ttq.admin.controller.resDto.UserInfoDto;
import com.tianzmp.ttq.admin.entity.UserInfo;
import com.tianzmp.ttq.admin.entity.UserInfoAttach;
import com.tianzmp.ttq.admin.enums.LockedEnum;
import com.tianzmp.ttq.admin.exception.AdminBusinessException;
import com.tianzmp.ttq.admin.exception.ErrorEnum;
import com.tianzmp.ttq.admin.mapper.UserInfoAttachMapper;
import com.tianzmp.ttq.admin.mapper.UserInfoMapper;
import com.tianzmp.ttq.admin.security.JwtUtils;
import com.tianzmp.ttq.admin.service.ILoginService;
import com.tianzmp.ttq.admin.service.IUserInfoService;
import com.tianzmp.ttq.admin.service.assemble.UserInfoAssemble;
import com.tianzmp.ttq.admin.service.assemble.UserInfoAttachAssemble;
import com.tianzmp.ttq.admin.util.AssertUtils;
import com.tianzmp.ttq.admin.util.MapperUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.catalina.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author zhumengping
 */
@Service
@Log4j2
public class LoginServiceImpl implements ILoginService {


    @Autowired
    private UserInfoMapper dao;

    @Autowired
    private UserInfoAttachMapper userInfoAttachDao;

    @Autowired
    private UserInfoAssemble userInfoAssemble;

    @Autowired
    private UserInfoAttachAssemble userInfoAttachAssemble;


    @Resource
    private IUserInfoService userInfoService;
    
    /**
    * 请描述一下这个方法是干嘛的
    * @param dto 
    * @return boolean
    * @author zhump
    * @date 2023/12/1 14:19
    */
    @Override
    @Transactional(readOnly = false, rollbackFor = AdminBusinessException.class)
    public boolean registerUser(UserInfoSaveDTO dto) {
        //通过账号去查询是否注册了，如果有账号，则不能再次新增
        LambdaQueryWrapper<UserInfo> eq = new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getAccount, dto.getAccount());
        List<UserInfo> userInfos = dao.selectList(eq);
        if (null != userInfos && userInfos.size() > 0){
            throw new AdminBusinessException(ErrorEnum.USER20000007);
        }


        UserInfo userInfo = userInfoAssemble.coversionDtoToBean(dto);
        String salt = UUID.randomUUID().toString().replace("-", "");
        String newPad = StringUtils.isNotBlank(dto.getPassword()) ? dto.getPassword() : dto.getAccount();
        userInfo.setPassword(DigestUtil.md5Hex(userInfo.getAccount()+ newPad + salt));
        userInfo.setSalt(salt);
        int insert = dao.insert(userInfo);
        UserInfoAttach attach = userInfoAttachAssemble.conversionDtoToBean(userInfo.getId(), dto);
        int result = userInfoAttachDao.insert(attach);
        AssertUtils.checkTrue(result <= 0 , ErrorEnum.USER20000002);
        return insert > 0;
    }

    @Override
    public UserInfoDto findByUserName(String account, String password) {
        List<UserInfo> list = dao.selectList(new QueryWrapper<UserInfo>().lambda().eq(UserInfo::getAccount, account));

        AssertUtils.notEmpty(list, ErrorEnum.USER20000004);

        UserInfo userInfo = list.get(0);
        AssertUtils.checkTrue(LockedEnum.LOCK.getLocked().equals(userInfo.getLocked()), ErrorEnum.USER20000001);

        String salt = userInfo.getSalt();
        String pwd = DigestUtil.md5Hex(userInfo.getAccount()+password + salt);

        AssertUtils.checkTrue(!pwd.equals(userInfo.getPassword()), ErrorEnum.USER20000006);

        UserInfoDto userInfoDto = MapperUtils.map(UserInfoDto.class, userInfo);


        LambdaQueryWrapper<UserInfoAttach> eq = new QueryWrapper<UserInfoAttach>().lambda().eq(UserInfoAttach::getUserId, userInfo.getId());
        List<UserInfoAttach> userInfoAttaches = userInfoAttachDao.selectList(eq);
        if (userInfoAttaches != null && userInfoAttaches.size() > 0){
            BeanUtils.copyProperties(userInfoAttaches.get(0),userInfoDto);
        }
        //获取权限
        List<String> permission = userInfoService.getPermission(userInfo.getId());
        if (null != permission && permission.size() > 0){
            userInfoDto.setPermission(permission);
        }

        Map<String,String> map = new HashMap<>(16);
        map.put("userId",userInfo.getId().toString());
        map.put("userName",userInfo.getUserName());
        String token = JwtUtils.createToken(map);
        userInfoDto.setToken(token);
        return userInfoDto;
    }


    @Override
    public boolean restPassword(Long userId) {
        UserInfo userInfo = dao.selectOne(new QueryWrapper<UserInfo>().lambda().eq(UserInfo::getId, userId));
        AssertUtils.isNull(userInfo, ErrorEnum.USER20000004);
        String salt = UUID.randomUUID().toString().replace("-", "");
        String pwd = DigestUtil.md5Hex(userInfo.getAccount()+userInfo.getAccount() + salt);
        UserInfo upUserInfo = new UserInfo();
        upUserInfo.setId(userId);
        upUserInfo.setPassword(pwd);
        upUserInfo.setSalt(salt);
        return dao.updateById(upUserInfo) > 0;
    }
}
